package com.tbl.modules.wms.service.Impl.outstorage;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.tbl.common.utils.PageTbl;
import com.tbl.common.utils.PageUtils;
import com.tbl.common.utils.StringUtils;
import com.tbl.modules.platform.dao.system.UserDAO;
import com.tbl.modules.platform.entity.system.User;
import com.tbl.modules.wms.constant.EmumConstant;
import com.tbl.modules.wms.dao.baseinfo.CarDAO;
import com.tbl.modules.wms.dao.baseinfo.ShelfDAO;
import com.tbl.modules.wms.dao.instorage.InstorageDetailDAO;
import com.tbl.modules.wms.dao.outstorage.OutStorageDetailDAO;
import com.tbl.modules.wms.dao.outstorage.OutstorageDAO;
import com.tbl.modules.wms.dao.outstorage.PrintOutDansDAO;
import com.tbl.modules.wms.dao.pda.SplitDAO;
import com.tbl.modules.wms.dao.storageinfo.StorageInfoDAO;
import com.tbl.modules.wms.entity.baseinfo.Car;
import com.tbl.modules.wms.entity.baseinfo.Shelf;
import com.tbl.modules.wms.entity.instorage.InstorageDetail;
import com.tbl.modules.wms.entity.outstorage.OutStorage;
import com.tbl.modules.wms.entity.outstorage.OutStorageDetail;
import com.tbl.modules.wms.entity.split.Split;
import com.tbl.modules.wms.entity.storageinfo.StorageInfo;
import com.tbl.modules.wms.entity.system.Printer;
import com.tbl.modules.wms.service.Impl.baseinfo.ShelfServiceImpl;
import com.tbl.modules.wms.service.Impl.webserviceImpl.WmsServiceImpl;
import com.tbl.modules.wms.service.outstorage.OutStorageService;
import com.tbl.modules.wms.service.system.PrinterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 出库信息
 * @author 70486
 */
@Service
public class OutstorageServiceImpl extends ServiceImpl<OutstorageDAO, OutStorage> implements OutStorageService {

    /**
     * 出库信息
     */
    @Autowired
    private OutstorageDAO outstorageDAO;
    /**
     * 库存信息
     */
    @Autowired
    private StorageInfoDAO storageInfoDAO;
    /**
     * 行车
     */
    @Autowired
    private CarDAO carDAO;
    /**
     * 人员
     */
    @Autowired
    private UserDAO userDAO;
    /**
     * 出库详情
     */
    @Autowired
    private OutStorageDetailDAO outStorageDetailDAO;
    /**
     * 发货单打印数据控制层
     */
    @Autowired
    private PrintOutDansDAO printOutDansDAO;
    /**
     * 库位管理
     */
    @Autowired
    private ShelfDAO shelfDAO;
    /**
     * 入库管理-订单详情
     */
    @Autowired
    private InstorageDetailDAO instorageDetailDAO;
    /**
     * 接口请求
     */
    @Autowired
    private WmsServiceImpl wmsService;
    /**
     * 打印配置服务
     */
    @Autowired
    private PrinterService printerService;
    /**
     * 库位
     */
    @Autowired
    private ShelfServiceImpl shelfServiceimpl;
    /**
     * 拆分库存
     */
    @Autowired
    private SplitDAO splitDAO;

    /**
     * 获取发货单列表数据
     * @param pageTbl
     * @param map 条件
     * @return PageUtils
     */
    @Override
    public PageUtils getPageList(PageTbl pageTbl, Map<String, Object> map) {
        String sortName = pageTbl.getSortname();
        String sortOrder = pageTbl.getSortorder();
        if (StringUtils.isEmptyString(sortName)) {
            sortName = "t1.id";
        }
        if (StringUtils.isEmptyString(sortOrder)) {
            sortOrder = "desc";
        }
        Page page = new Page(pageTbl.getPageno(), pageTbl.getPagesize(), sortName, "asc".equalsIgnoreCase(sortOrder));
        return new PageUtils(page.setRecords(outstorageDAO.getPageList(page, map)));
    }

    /**
     *获取打印出库单列表数据
     * @param pageTbl
     * @param map 查询条件
     * @return PageUtils
     */
    @Override
    public PageUtils getPrintPageList(PageTbl pageTbl, Map<String, Object> map) {
        Page page = new Page(pageTbl.getPageno(), pageTbl.getPagesize(), StringUtils.isEmptyString(pageTbl.getSortname()) ? "t2.id" :
        pageTbl.getSortname(), "asc".equalsIgnoreCase(StringUtils.isEmptyString(pageTbl.getSortorder()) ? "asc" : pageTbl.getSortorder()));
//        List<OutStoragePrint> lstOutStoragePrint =new ArrayList<>();
//        if(map!=null && map.get("outno")!=null && !"".equals(map.get("outno"))){
//            Map<String,Object> mapInfo = printOutDansDAO.getOutPrintInfo(map.get("outno").toString());
//            if(mapInfo!=null && mapInfo.get("BATCH_NO")!=null){
//                map.put("batch_no",mapInfo.get("BATCH_NO").toString());
//                lstOutStoragePrint = outstorageDAO.getPrintPageList(page, map);
//            }
//        }
        return new PageUtils(page.setRecords(outStorageDetailDAO.findOutstorageDetailByCarNo(page, map)));
    }

    /**
     * 发货执行数据
     * @param pageTbl
     * @param id 出库单主键
     * @return PageUtils
     */
    @Override
    public PageUtils getDetailList(PageTbl pageTbl, Integer id) {
        String sortName = pageTbl.getSortname();
        String sortOrder = pageTbl.getSortorder();
        if (StringUtils.isEmptyString(sortName)||"cz".equals(sortName)) {
            sortName = "id";
        }
        if (StringUtils.isEmptyString(sortOrder)) {
            sortOrder = "desc";
        }

        Page page = new Page(pageTbl.getPageno(), pageTbl.getPagesize(), sortName, "asc".equalsIgnoreCase(sortOrder));
        return new PageUtils(page.setRecords(outstorageDAO.getDetailList(page, id)));
    }

    /**
     * 获取Excel列表数据
     * @param map
     * @return List<OutStorage>
     */
    @Override
    public List<OutStorage> getExcelList(Map<String, Object> map) {
        List<OutStorage> lstOutStorage = outstorageDAO.getExcelList(map);
        lstOutStorage.forEach(a->{
            if (StringUtils.isNotBlank(a.getStorageState())){
                if (a.getStorageState().indexOf(2)>-1) {
                    a.setStorageState("出库中");
                } else if (a.getStorageState().indexOf(1)>-1) {
                    if (a.getStorageState().indexOf(3)>-1){
                        a.setStorageState("出库中");
                    }else {
                        a.setStorageState("未出库");
                    }
                } else if (StringUtils.isNotEmpty(a.getStorageState())) {
                    a.setStorageState("出库完成");
                } else {
                    a.setStorageState("无数据");
                }

            }else {
                a.setStorageState("无数据");
            }
        });
        return lstOutStorage;
    }

    /**
     * 获取查看明细Excel列表数据
     * @param map 条件
     * @return List<OutStorage> 出库单主表列表
     */
    @Override
    public List<OutStorageDetail> getDetailExcelList(Map<String, Object> map) {
        return outstorageDAO.getDetailExcelList(map);
    }

    /**
     * 更新主表信息
     * @param outStorage 出库单
     * @return boolean
     */
    @Override
    public boolean saveOutStorage(OutStorage outStorage) {
        return outstorageDAO.updateById(outStorage)>0;
    }

    /**
     * 点击提交更新主表状态为已提交
     * @param outStorage 出库单
     * @return boolean
     */
    @Override
    public boolean subOutStorage(OutStorage outStorage) {
        return outstorageDAO.updateById(outStorage)>0;
    }

    /**
     * 获取到质保单号列表
     * @param pageTbl
     * @param map 条件
     * @return PageUtils
     */
    @Override
    public PageUtils getQaCode(PageTbl pageTbl, Map<String, Object> map) {
        Page<Map<String, Object>> page = new Page<>(pageTbl.getPageno(), pageTbl.getPagesize());
        return new PageUtils(page.setRecords(outstorageDAO.getQaCode(page, map)));
    }

    /**
     * 发货单详情添加
     * @param id 发货单主表主键
     * @param qaCodeIds 标签初始化主键
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOutstorageDetail(Long id, String[] qaCodeIds) {
        List<Long> idList = Arrays.stream(qaCodeIds).map(Long::parseLong).distinct().collect(Collectors.toList());
        idList.forEach(a -> {
            InstorageDetail instroageDetail = instorageDetailDAO.selectById(a);
            OutStorageDetail outStorageDetail = new OutStorageDetail();
            outStorageDetail.setMaterialCode(instroageDetail.getMaterialCode());
            outStorageDetail.setBatchNo(instroageDetail.getBatchNo());
            outStorageDetail.setQaCode(instroageDetail.getQaCode());
            outStorageDetail.setShelfCode(instroageDetail.getShelfCode());
            outStorageDetail.setPId(id);
            outStorageDetail.setRfid(instroageDetail.getRfid());
            outStorageDetail.setMeter(instroageDetail.getMeter());
            outStorageDetail.setWarehouseCode(instroageDetail.getWarehouseCode());
            outStorageDetail.setOrg(instroageDetail.getFactoryCode());
            outStorageDetail.setDishnumber(instroageDetail.getDishnumber());
            outStorageDetail.setUnit(instroageDetail.getUnit());
            outStorageDetail.setOrderline(instroageDetail.getOrderline());
            outStorageDetail.setOrderno(instroageDetail.getOrdernum());
            outStorageDetail.setUnit(instroageDetail.getUnit());
            outStorageDetailDAO.insert(outStorageDetail);

            StorageInfo storageInfo = storageInfoDAO.selectOne(new StorageInfo() {{
            	setQaCode(instroageDetail.getQaCode());
            }});
            if(storageInfo!=null) {
            	storageInfo.setState(EmumConstant.storageInfoState.LOCKING.getCode());
            	storageInfoDAO.updateById(storageInfo);
            }
        });
        return true;
    }

    /**
     * 删除发货单管理详情数据
     * @param ids 出库详情主键
     * @return Map<String,Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> deleteOutStorageDetailIds(String[] ids) {
        Map<String, Object> map = new HashMap<>();
        AtomicBoolean result = new AtomicBoolean(true);
        List<Long> idList = StringUtils.toLongList(ids);
        if (idList!=null) {
            idList.forEach(a -> {
                OutStorageDetail outStorageDetail = outStorageDetailDAO.selectById(a);
                if (EmumConstant.outstorageDetailState.OUTSTORAGING.getCode().equals(outStorageDetail.getState())
                        || EmumConstant.outstorageDetailState.OUTSTORAGED.getCode().equals(outStorageDetail.getState())) {
                    result.set(false);
                }
                StorageInfo storageInfo = storageInfoDAO.selectOne(new StorageInfo() {{
                    setQaCode(outStorageDetail.getQaCode());
                }});
                if (storageInfo != null) {
                    storageInfo.setState(EmumConstant.storageInfoState.NORMAL.getCode());
                    storageInfoDAO.updateById(storageInfo);
                }
            });
        }
        if (!result.get()) {
            map.put("msg", "非生效状态，无法删除！");
            map.put("result", result.get());
            return map;
        }
        result.set(outStorageDetailDAO.deleteBatchIds(idList) > 0);
        map.put("msg", result.get() ? "删除成功！" : "删除失败！");
        map.put("result", result.get());
        return map;
    }

    /**
     * 绑定行车
     * @param outStorageDetail 出库单明细信息
     * @return boolean
     */
    @Override
    public boolean saveCar(OutStorageDetail outStorageDetail) {
        outStorageDetail.setCarCode(carDAO.selectById(outStorageDetail.getCarId()).getCode());
        return outStorageDetailDAO.updateById(outStorageDetail)>0;
    }

    /**
     * 根据行车编码获取行车
     * @param warehouseCode 仓库编码
     * @param org 所属厂区
     * @return List<Car> 行车列表
     */
    @Override
    public List<Car> selectCarListByWarehouseCode(String warehouseCode,List<String> org) {
        return outstorageDAO.selectCarListByWarehouseCode(warehouseCode,org);
    }

    /**
     * 点击出库执行，点击开始拣货
     * @param id 出库单明细主键
     * @param userId 操作人id
     * @return boolean
     */
    @Override
    public boolean detailStart(Long id, Long userId) {
        OutStorageDetail outStorageDetail = outStorageDetailDAO.selectById(id);
        outStorageDetail.setState(EmumConstant.outstorageDetailState.OUTSTORAGING.getCode());
        outStorageDetail.setStartStorageTime(new Date());
        outStorageDetail.setOutStorageId(userId);
        outStorageDetail.setStartpicktime(new Date());

        carDAO.updateCarByCode(outStorageDetail.getCarCode(),"",Long.valueOf(EmumConstant.carState.OUTSTORAGING.getCode()));
        return outStorageDetailDAO.updateById(outStorageDetail)>0;
    }

    /**
     * 点击出库执行，点击拣货完成
     * @param id 出库单详情主键
     * @param userId 用户主键
     * @param outtime 出库时间
     * @param isPrint 是否打印出库单
     * @return Map<String, Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object>  detailSuccess(Long id, Long userId, String outtime, Integer isPrint) {
        Map<String, Object> resultMap = new HashMap<>();
        OutStorageDetail outStorageDetail = outStorageDetailDAO.selectById(id);
        List<StorageInfo> lstStorageInfo = storageInfoDAO.selectList(new EntityWrapper<StorageInfo>()
                .eq("QACODE",outStorageDetail.getQaCode()));
        if (lstStorageInfo==null || lstStorageInfo.size()==0){
            resultMap.put("result", false);
            resultMap.put("msg", "库存中没有此货物，请联系管理员查看！");
            return resultMap;
        }

        //判断打印机配置是否已经配置完成
        Printer printer = printerService.findPrinterCodeByUserId(userId);
        if (isPrint != 1 && printer == null){
            resultMap.put("result", false);
            resultMap.put("msg", "打印机配置项错误，请联系管理员查看！");
            return resultMap;
        }

        StorageInfo storageInfo = lstStorageInfo.get(0);
        User user = userDAO.selectById(userId);
        OutStorage outStorage = outstorageDAO.selectById(outStorageDetail.getPId());
        //调出库接口
        Map<String,Object> xmlMap = new HashMap<>(1);
        xmlMap.put("line", new HashMap<String, Object>(5) {{
            put("type", isPrint);
            put("printcode", printer.getPrinterStr());
        	put("outno", outStorage.getShipNo());
            put("outtime", outtime);
        	put("userno", user.getUsername());
        	put("batchs",new HashMap<String,Object>(1){{
        		put("batch",new HashMap<String,Object>(2){{
                    put("qacode", outStorageDetail.getQaCode());
                    put("deliverno", outStorageDetail.getStartstorageid() == null ? userDAO.selectById(userId).getUsername() :
                            userDAO.selectById(outStorageDetail.getStartstorageid()).getUsername());
                }});
        	}});
        }});
        //当即调用接口
        Map<String,Object> returnMap = wmsService.FEWMS002(xmlMap, outStorageDetail.getQaCode(), outStorageDetail.getBatchNo());
        String returnData = returnMap.get("returnData").toString().replaceAll(" ", "");
        boolean issuccess = returnData.contains("<code>0</code>") || returnData.contains("\"code\":0") || returnData.contains("S000A000");

        //如果成功，扣减库存
        if(issuccess) {
            List<Split> lstSplit = splitDAO.selectList(new EntityWrapper<Split>().eq("BATCH_NO", outStorageDetail.getBatchNo()));
            /*先看看拆分表有没有这个批次的，如果有，那么就是已经在wms做过拆分的了，那么就不需要动到库存，直接动拆分库里的库存即可，而且拆分表中不会还有再拆分，肯定是
            直接出库，如果没有，就去库存中扣减（没有在wms分盘，所以要修改库存的米数）*/
            if (lstSplit.size()>0){
                lstSplit.forEach(split -> {
                    //状态设为出库完成
                    split.setState(4);
                    splitDAO.updateById(split);
                    /*
                    一、无预出库（下架）扫码直接出库的模式
                    此种模式没有划单，拣货下架模块会被屏蔽，那么扫码出库的时候就释放库位，对应在应用平台点击出库时，也需要释放库位（因为如果扫码出库成功了，
                    那么库位也就对应释放了，线盘的状态是出库成功，平台上就点不了出库了，如果扫码出库失败或者漏扫未扫，那么状态仍然符合在应用平台出库的条件，
                    那么在平台出库时，也就是对应要释放库位的）。
                    二、有预出库（下架）扫码预出库的模式
                    如果扫码下架了，或者在应用平台下架界面中完成了下架操作，那么出库就不需要释放库位了，如果漏扫了或者没有在下架界面中完成下架操作直接去出库的，
                    那么就是要释放库位。

                    综上所属，只要根据出库明细的状态来判断，如果出库明细状态到了预出库阶段，那么说明肯定已经释放库位了，就不需要再释放了，否则就需要
                    */
                    if (!EmumConstant.outstorageDetailState.OUTSTORAGE_PREPARE.getCode().equals(outStorageDetail.getState())){
                        shelfServiceimpl.setShelfState(split.getShelfCode(), split.getOrg(), split.getWarehouseCode(),
                                EmumConstant.sheflState.AVAILABLE.getCode());
                    }
                });
            }else {
                //剩余米数
                String leftMeter = String.valueOf(Float.parseFloat(storageInfo.getMeter()) - Float.parseFloat(outStorageDetail.getMeter()));
                //全部出库
                if ("0".equals(leftMeter) || "0.0".equals(leftMeter)) {
                    storageInfoDAO.deleteById(storageInfo.getId());
                    if (!EmumConstant.outstorageDetailState.OUTSTORAGE_PREPARE.getCode().equals(outStorageDetail.getState())){
                        shelfServiceimpl.setShelfState(storageInfo.getShelfCode(), storageInfo.getOrg(), storageInfo.getWarehouseCode(),
                                EmumConstant.sheflState.AVAILABLE.getCode());
                    }
                } else {
                    //按米出
                    storageInfo.setState(EmumConstant.storageInfoState.NORMAL.getCode());
                    storageInfo.setMeter(leftMeter);
                    storageInfoDAO.updateById(storageInfo);
                }
            }

            //恢复行车状态为可用
            carDAO.updateCarByCode(outStorageDetail.getCarCode(), "", Long.valueOf(EmumConstant.carState.UNUSED.getCode()));
            //确认出库时间
            outStorageDetail.setOutStorageTime(new Date());
            //确认出库人
            outStorageDetail.setOutStorageId(userId);
            outStorageDetail.setState(EmumConstant.outstorageDetailState.OUTSTORAGED.getCode());
            outStorageDetailDAO.updateById(outStorageDetail);

            resultMap.put("result", true);
            resultMap.put("msg", "出库成功！");
        }else {
            resultMap.put("result", false);
            resultMap.put("msg", returnData);
        }

        return resultMap;
    }

    /**
     * 批量完成出库
     * @param lstIds 出库单详情主键
     * @param userId 用户主键
     * @param outtime 出库时间
     * @param isPrint 是否需要打印：3既出库又打印；2纯打印；1纯出库
     * @return Map<String,Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String,Object> outsStorageOut(List<Long> lstIds, Long userId, String outtime, Integer isPrint) {
        Map<String,Object> resultMap = Maps.newHashMap();
        if (lstIds==null||lstIds.size()==0){
            resultMap.put("result", false);
            resultMap.put("msg","所选货物都已出库完毕，无需再次出库！");
            return resultMap;
        }

        //判断打印机配置是否已经配置完成
        Printer printer = printerService.findPrinterCodeByUserId(userId);
        if (isPrint != 1 && printer == null){
            resultMap.put("result", false);
            resultMap.put("msg", "打印机配置项错误，请联系管理员查看！");
            return resultMap;
        }

        List<String> lstCarCode = new ArrayList<>(), lstShelfCodeComplete = new ArrayList<>();
        List<Long> storageInfoIdsList = new ArrayList<>();
        Map<String, Object> batch = Maps.newIdentityHashMap();
        Map<String, Object> qdgroup;
        StringBuilder qacodeBuilder = new StringBuilder(), batchnoBuilder = new StringBuilder();

        //平台登陆人员
        String wmsLoginer = userDAO.selectById(userId).getUsername();
        //根据出库详情主键查询详情及对应货物在库存的主键
        List<OutStorageDetail> lstOutStorageDetail = outStorageDetailDAO.findBatchOutstorageDetail(lstIds);
        if (lstOutStorageDetail!=null) {
            for (OutStorageDetail outStorageDetail : lstOutStorageDetail) {
                qdgroup = Maps.newHashMap();
                qdgroup.put("qacode", outStorageDetail.getQaCode());
                qdgroup.put("deliverno", outStorageDetail.getStartstorageid() == null ? wmsLoginer :
                        userDAO.selectById(outStorageDetail.getStartstorageid()).getUsername());
                //new String必须加
                batch.put(new String("batch"), qdgroup);

                if (StringUtils.isNotEmpty(outStorageDetail.getCarCode())) {
                    lstCarCode.add(outStorageDetail.getCarCode());
                }

                if (outStorageDetail.getStorageInfoId() != null) {
                    StorageInfo storageInfo = storageInfoDAO.selectById(outStorageDetail.getStorageInfoId());
                    List<Split> lstSplit = splitDAO.selectList(new EntityWrapper<Split>().eq("BATCH_NO",outStorageDetail.getBatchNo()));
                    if (lstSplit.size()>0){
                        lstSplit.forEach(split -> {
                            //状态设为出库完成
                            split.setState(4);
                            splitDAO.updateById(split);
                            //如果状态是预出库（下架），那么说明肯定是扫码出库过了，也就是已经释放过库位了，这样的情况下不能再次释放
                            if (!EmumConstant.outstorageDetailState.OUTSTORAGE_PREPARE.getCode().equals(outStorageDetail.getState())){
                                Shelf shelf = shelfDAO.selectOne(new Shelf(){{
                                    setCode(split.getShelfCode());
                                    setWarehouseCode(split.getWarehouseCode());
                                    setFactoryCode(split.getOrg());
                                }});
                                lstShelfCodeComplete.add(shelf.getCodeComplete());
                            }
                        });
                    }else {
                        //剩余米数
                        String leftMeter=String.valueOf(Float.parseFloat(storageInfo.getMeter())-Float.parseFloat(outStorageDetail.getMeter()));
                        //全部出库
                        if ("0".equals(leftMeter) || "0.0".equals(leftMeter)) {
                            storageInfoIdsList.add(outStorageDetail.getStorageInfoId());
                            if (!EmumConstant.outstorageDetailState.OUTSTORAGE_PREPARE.getCode().equals(outStorageDetail.getState())){
                                Shelf shelf = shelfDAO.selectOne(new Shelf(){{
                                    setCode(storageInfo.getShelfCode());
                                    setWarehouseCode(storageInfo.getWarehouseCode());
                                    setFactoryCode(storageInfo.getOrg());
                                }});
                                lstShelfCodeComplete.add(shelf.getCodeComplete());
                            }
                        } else {
                            //按米
                            storageInfo.setMeter(leftMeter);
                            storageInfo.setState(EmumConstant.storageInfoState.NORMAL.getCode());
                            storageInfoDAO.updateById(storageInfo);
                        }
                    }
                }
                outStorageDetail.setState(EmumConstant.outstorageDetailState.OUTSTORAGED.getCode());
                outStorageDetail.setOutStorageId(userId);
                outStorageDetail.setOutStorageTime(new Date());

                qacodeBuilder.append(outStorageDetail.getQaCode()).append(",");
                batchnoBuilder.append(outStorageDetail.getBatchNo()).append(",");
            }
        }

        //出库接口调用返回成功与否标志
        boolean issuccess = false;
        //出库接口返回结果
        String returnData = "";
        if (lstOutStorageDetail!=null && lstOutStorageDetail.size()>0) {
            String shipno = outstorageDAO.selectById(lstOutStorageDetail.get(0).getPId()).getShipNo();
            //调出库接口
            Map<String, Object> xmlMap = new HashMap<>(1);
            xmlMap.put("line", new HashMap<String, Object>(5) {{
                put("printcode", printer.getPrinterStr());
                put("type", isPrint);
                put("outno", shipno);
                put("outtime", outtime);
                put("userno", wmsLoginer);
                put("batchs", batch);
            }});
            //当即调用接口
            Map<String, Object> returnMap = wmsService.FEWMS002(xmlMap, qacodeBuilder.toString(), batchnoBuilder.toString());
            returnData = returnMap.get("returnData").toString().replace(" ", "");
            String returnDataTrim = returnData.replace(" ", "");
            //出库接口调用返回成功与否标志
            issuccess = returnDataTrim.contains("<code>0</code>")||returnDataTrim.contains("\"code\":0")||returnDataTrim.contains("S000A000");
        }

        if (issuccess) {
            //批量删除库存
            if (storageInfoIdsList.size() > 0) {
                storageInfoDAO.deleteBatchIds(storageInfoIdsList);
            }

            //批量修改出库单明细的状态，添加出库人员
            if (lstOutStorageDetail.size() > 0) {
                outStorageDetailDAO.updateOutstorageDetailBatches(lstOutStorageDetail);
            }

            //批量设置库位可用
            if (lstShelfCodeComplete.size() > 0) {
                Shelf shelf = new Shelf();
                shelf.setState(EmumConstant.sheflState.AVAILABLE.getCode());
                shelfDAO.update(shelf, new EntityWrapper<Shelf>().in("CODE_COMPLETE", lstShelfCodeComplete));
            }

            //批量设置行车可用
            if (lstCarCode.size() > 0) {
                Car car = new Car();
                car.setState(Long.valueOf(EmumConstant.carState.UNUSED.getCode()));
                carDAO.update(car, new EntityWrapper<Car>().in("CODE", lstCarCode));
            }

            resultMap.put("result", true);
            resultMap.put("msg","出库成功！");
        }else {
            resultMap.put("result", false);
            resultMap.put("msg",returnData);
        }

        return resultMap;
    }

    /**
     * 获取打印发货单明细信息
     * @param wayno 运单号
     * @param outno 出库单
     * @param type 类型
     * @return List<Map<String, Object>>
     */
    @Override
    public List<Map<String, Object>> getPrintInfo(String wayno,String outno,String type) {
        List<Map<String,Object>> list;
        List<Map<String,Object>> list_new = new ArrayList<>();
        Map<String,Object> params = new HashMap<>(1);

        if(wayno!=null && wayno.length()>0){
            params.put("outnoList",Arrays.asList(wayno.split(",")));
            list = printOutDansDAO. getOutPrintInfoByList(params);
        }else{
            params.put("batchno",printOutDansDAO.getOutPrintInfo(outno).get("BATCH_NO").toString());
            list = printOutDansDAO.getPrintListByBatchno(params);
        }

        list.forEach(map -> {
            List<Map<String,Object>> listArr = printOutDansDAO.getPrintOutDetail((String) map.get("ID1"));
            map.put("detail",listArr);
            map.put("username",listArr!=null && listArr.size()>0 ? listArr.get(0).get("USERNAME")==null?"":listArr.get(0).get("USERNAME"):"");

            list_new.add(map);
        });

        return list_new;
    }


    /**
     * 点击打印按钮，根据车牌号获取列表数据
     * @param pageTbl 分页工具页面类
     * @param wayno 运单号
     * @return PageUtils
     */
    @Override
    public PageUtils getPrintPageList1(PageTbl pageTbl,String wayno) {
        String sortName = pageTbl.getSortname();
        String sortOrder = pageTbl.getSortorder();
        if (StringUtils.isEmptyString(sortName)) {
            sortName = "car";
        }
        Page page = new Page(pageTbl.getPageno(), pageTbl.getPagesize(), sortName, "asc".equalsIgnoreCase(sortOrder));
        return new PageUtils(page.setRecords(outstorageDAO.getPrintPageList1(page, wayno)));
    }

    /**
     * 根据输入的提货单号获取车辆及货物信息
     * @param shipNo 提货单号
     * @return Map<String,Object>
     */
    @Override
    public List<Map<String,Object>> getOutstorageListByCarNo(String shipNo){
        return outstorageDAO.getOutstorageListByCarNo(shipNo);
    }
}
